home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / program / ccdl150l.zip / IO / SPRINTF.C < prev    next >
C/C++ Source or Header  |  1997-03-09  |  6KB  |  297 lines

  1. #include <stdio.h>
  2. #include <ctype.h>
  3. #include <string.h>
  4.  
  5. /* Floating point not implemented */
  6.  
  7. #define NUM_SIZE 32
  8. static int getnum(char *string, int num,int radix,int lc,int unsign)
  9. {
  10.     int i,sz=0;
  11.     unsigned unum;
  12.     for (i=0; i < NUM_SIZE-1; i++)
  13.         string[i] = '0';
  14.     string[NUM_SIZE-1] = 0;
  15.     if (num < 0 && !unsign)
  16.         unum = - num;
  17.     else
  18.         unum = num;
  19.     i = NUM_SIZE-2;
  20.     while (unum) {
  21.         string[i] = (char)((unum % radix)+ '0');
  22.         if (string[i] > '9') {
  23.             string[i] += 7;
  24.             if (lc)
  25.                 string[i] += 32;
  26.         }
  27.         i--;
  28.         unum /= radix;
  29.         sz++;
  30.     }
  31.     if (sz == 0)
  32.         sz++;
  33.     return sz;
  34. }
  35. static char *onetostr(char *obuf,char **buffer, const char *format, void *arg,int *count)
  36. {
  37.  
  38.     int c,sz;
  39.     int *p;
  40.     int looping = 1;
  41.     int issigned = 0, ljustify = 0, spaced = 0, prefixed = 0;
  42.     int    leadzero = 0;
  43.     int width = 0;
  44.     int prec = 6;
  45.     int mode = 0;
  46.     int lc,i;
  47.     char locbuf[NUM_SIZE],*ofm = format;
  48.     while (looping) 
  49.         switch (*format) {
  50.             case '+':    issigned = 1;
  51.                     format++;
  52.                     break;
  53.             case '-':    ljustify = 1;
  54.                     format++;
  55.                     break;
  56.             case ' ': spaced = 1;
  57.                     format++;
  58.                     break;
  59.             case '#': prefixed = 1;
  60.                     format++;
  61.                     break;
  62.             case '0':    leadzero = 1;
  63.                     format++;
  64.                     break;
  65.             default:
  66.                     looping = 0;
  67.         }
  68.     if (isdigit(*format)) {
  69.         width = 0;
  70.         while (isdigit(*format)) {
  71.             width *= 10;
  72.             width += *format++ - '0';
  73.         }
  74.     }
  75.     if (*format == '.') {
  76.         format++;
  77.         prec = 0;
  78.         while (isdigit(*format)) {
  79.             prec *= 10;
  80.             prec += *format++ - '0';
  81.         }
  82.     }
  83.     if (*format == 'h' || *format == 'l' || *format == 'L')
  84.         mode = *format++;
  85.     switch (*format++) {
  86.         case '%':
  87.             *(*buffer)++ = '%';
  88.             *(*buffer) = 0;
  89.             break;
  90.         case 'c':
  91.             (*count)++;
  92.             c = *(int *)arg;
  93.             *(*buffer)++ = (char)c;
  94.             *(*buffer) = 0;
  95.             break;
  96.         case 'd':
  97.         case 'i':
  98.             (*count)++;
  99.             c = *(int *)arg;
  100.             if (mode == 'h') {
  101.                 c &= 0xffff;
  102.                 if (c & 0x8000)
  103.                     c |= 0xffff0000;
  104.             }
  105.             sz = getnum(locbuf,c,10,0,0);
  106.             if (issigned) {
  107.                 if (c < 0) 
  108.                     *(*buffer)++ = '-';
  109.                 else
  110.                     *(*buffer)++ = '+';
  111.                 if (width)
  112.                     width--;
  113.             }
  114.             else if (spaced) {
  115.                 if (c < 0) 
  116.                     *(*buffer)++ = '-';
  117.                 else
  118.                     *(*buffer)++ = ' ';
  119.                 if (width)
  120.                     width--;
  121.             }
  122.             else {
  123.                 if (c < 0) {
  124.                     *(*buffer)++ = '-';
  125.                     if (width)
  126.                         width--;
  127.                 }
  128.             }
  129.             goto numfin;
  130.                 
  131.         case 'e':
  132.         case 'E':
  133.         case 'f':
  134.         case 'g':
  135.         case 'G':
  136. #ifndef USE_FLOAT
  137.             (*count)++;
  138.             if (mode == 'L')
  139.                 (*count)++;
  140.             strcpy(*buffer,"FP not linked");
  141.             *buffer += strlen(*buffer);
  142. #endif
  143.             break;
  144.         case 'n':
  145.             (*count)++;
  146.             p = *(int **)arg;
  147.             *p = (int)((*buffer) - obuf);
  148.             break;
  149.         case 'o':
  150.             (*count)++;
  151.             c = *(int *)arg;
  152.             if (mode == 'h') {
  153.                 c &= 0xffff;
  154.                 if (c & 0x8000)
  155.                     c |= 0xffff0000;
  156.             }
  157.             sz = getnum(locbuf,c,8,0,1);
  158.             if (prefixed && c)
  159.                 sz--;
  160.             if (issigned) {
  161.                 *(*buffer)++ = '+';
  162.                 if (width)
  163.                     width--;
  164.             }
  165.             else if (spaced) {
  166.                 *(*buffer)++ = ' ';
  167.                 if (width)
  168.                     width--;
  169.             }
  170.             goto numfin;
  171.         case 's':
  172.             (*count)++;
  173.             sz = strlen(*(char **)arg);
  174.             if (width && (sz < width))
  175.                 if (ljustify) {
  176.                     for (i=0; i < width-sz; i++)
  177.                         *(*buffer)++ = ' ';
  178.                     strcpy(*buffer,*(char **)arg);
  179.                      *buffer += strlen(*buffer);
  180.                 }
  181.                 else {
  182.                     strcpy(*buffer,*(char **)arg);
  183.                      *buffer += strlen(*buffer);
  184.                     for (i=0; i < width-sz; i++)
  185.                         *(*buffer)++ = ' ';
  186.                 }
  187.             else {
  188.                 strcpy(*buffer,*(char **)arg);
  189.                 *buffer += strlen(*buffer);
  190.             }
  191.             break;
  192.         case 'u':
  193.             (*count)++;
  194.             c = (int )arg;
  195.             if (mode == 'h') {
  196.                 c &= 0xffff;
  197.                 if (c & 0x8000)
  198.                     c |= 0xffff0000;
  199.             }
  200.             sz = getnum(locbuf,*(int *)arg,10,0,1);
  201.  
  202.             if (issigned) {
  203.                 *(*buffer)++ = '+';
  204.                 if (width)
  205.                     width--;
  206.             }
  207.             else if (spaced) {
  208.                 *(*buffer)++ = ' ';
  209.                 if (width)
  210.                     width--;
  211.             }
  212.             goto numfin;
  213.         case 'x':
  214.         case 'p':
  215.                     lc = 1;
  216.         case 'X':
  217.             (*count)++;
  218.             if (*(format-1) == 'X')
  219.                 lc = 0;
  220.             c = *(int *)arg;
  221.             if (mode == 'h') {
  222.                 c &= 0xffff;
  223.                 if (c & 0x8000)
  224.                     c |= 0xffff0000;
  225.             }
  226.             sz = getnum(locbuf,c,16,lc,1);
  227.             if (issigned) {
  228.                 *(*buffer)++ = '+';
  229.                 if (width)
  230.                     width--;
  231.             }
  232.             else if (spaced) {
  233.                 *(*buffer)++ = ' ';
  234.                 if (width)
  235.                     width--;
  236.             }
  237.             if (prefixed) {
  238.                 *(*buffer)++ = '0';
  239.                 *(*buffer)++ = 'x';
  240.             }
  241. numfin:
  242.             if (width) {
  243.                 if (width <= sz) {
  244.                     goto nowidth;
  245.                 }
  246.                 if (!ljustify || leadzero) {
  247.                     if (leadzero) {
  248.                         for (i=0; i < width-sz; i++)
  249.                             *(*buffer)++ = '0';
  250.                     }
  251.                     else {
  252.                         for (i=0; i < width-sz; i++)
  253.                             *(*buffer)++ = ' ';
  254.                     }
  255.                     strcpy(*buffer,&locbuf[NUM_SIZE-sz-1]);
  256.                     (*buffer) += strlen(*buffer);
  257.                 }
  258.                 else {
  259.                     strcpy(*buffer,&locbuf[NUM_SIZE-sz-1]);
  260.                     (*buffer) += strlen(*buffer);
  261.                     for (i=0; i < width-sz; i++)
  262.                         *(*buffer)++ = ' ';
  263.                     *(*buffer) = 0;
  264.                 }
  265.             }
  266.             else {
  267. nowidth:
  268.                 strcpy(*buffer,&locbuf[NUM_SIZE-sz-1]);
  269.                 (*buffer) += strlen(*buffer);
  270.                 *(*buffer) = 0;
  271.             }
  272.             break;
  273.         default:
  274.              *(*buffer)++ = '%';
  275.             format = ofm;
  276.             break;
  277.     }
  278.     return(format);
  279. }
  280. int vsprintf(char *buffer, const char *format,
  281.                                     void *arglist)
  282. {
  283.     int i = 0;
  284.     char *obuf = buffer;
  285.     while (*format) {
  286.         while (*format != '%' && *format != 0)
  287.             *buffer++ = *format++;
  288.         if (*format && *(format+1))
  289.             format = onetostr(obuf,&buffer,format+1,&((char **)arglist+i),&i);
  290.     }
  291.     *buffer++ = 0;
  292.     return(strlen(obuf));
  293. }
  294. int sprintf(char *buffer, const char *format, ...)
  295. {
  296.     return vsprintf(buffer,format,(((char *)&format) + sizeof(char *)));
  297. }